-
Notifications
You must be signed in to change notification settings - Fork 11.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[jsonrpc] fix estimated rewards during safe mode #20182
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
3 Skipped Deployments
|
return rates; | ||
} | ||
|
||
let min_epoch = *rates.iter().map(|(e, _)| e).min().unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's probably easier to sort it first before processing.
But otherwise this code looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if sorting it first will make things easier because then we'd have to keep track of the index we are at separately and insert the missing entry, etc. The logic may get messier. Unless I'm missing something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You just iterate the sorted vector. No need for min/max/find calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the alternative implementation I came up with:
fn backfill_rates(
mut rates: Vec<(EpochId, PoolTokenExchangeRate)>,
) -> Vec<(EpochId, PoolTokenExchangeRate)> {
if rates.is_empty() {
return rates;
}
rates.sort_by(|(a, _), (b, _)| a.cmp(b));
let mut filled_rates = vec![];
let mut next_epoch_to_fill = rates[0].0;
let mut prev_rate = rates[0].1.clone();
for (epoch, rate) in rates {
// Fill in all the gaps between the previous entry and the current entry.
while epoch > next_epoch_to_fill {
filled_rates.push((next_epoch_to_fill, prev_rate.clone()));
next_epoch_to_fill += 1;
}
filled_rates.push((next_epoch_to_fill, rate.clone()));
next_epoch_to_fill += 1;
prev_rate = rate;
}
filled_rates.reverse();
filled_rates
}
I think this is harder to understand and get right. It took me quite a few tries to get the code right, with off-by-one errors etc
@@ -431,7 +432,8 @@ async fn exchange_rates( | |||
}) | |||
.collect::<Result<Vec<_>, _>>()?; | |||
|
|||
rates.sort_by(|(a, _), (b, _)| a.cmp(b).reverse()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is line 466/467 attempting to do the equivalent of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The loop in backfill_rates
does backfilling + sorting in ascending order by epoch number. And line 484 reverses the vector so it becomes sorted in descending order.
## Description Currently if the exchange rate for an epoch is not found, we would assign it the default exchange rate while we should've used the exchange rate from the previous existing epoch instead. This PR fixes that. ## Test plan Added some unit tests. --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [x] JSON-RPC: fixed reward estimation in `getStakes` API so that we don't overestimate stake rewards of stakes activated during safe mode epochs. - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
## Description Currently if the exchange rate for an epoch is not found, we would assign it the default exchange rate while we should've used the exchange rate from the previous existing epoch instead. This PR fixes that. ## Test plan Added some unit tests. --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [x] JSON-RPC: fixed reward estimation in `getStakes` API so that we don't overestimate stake rewards of stakes activated during safe mode epochs. - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
## Description Currently if the exchange rate for an epoch is not found, we would assign it the default exchange rate while we should've used the exchange rate from the previous existing epoch instead. This PR fixes that. ## Test plan Added some unit tests. --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [x] JSON-RPC: fixed reward estimation in `getStakes` API so that we don't overestimate stake rewards of stakes activated during safe mode epochs. - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
@@ -451,6 +453,38 @@ pub struct ValidatorExchangeRates { | |||
pub rates: Vec<(EpochId, PoolTokenExchangeRate)>, | |||
} | |||
|
|||
/// Backfill missing rates for some epochs due to safe mode. If a rate is missing for epoch e, | |||
/// we will use the rate for epoch e-1 to fill it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"we will use the value from the nearest prior epoch"
Description
Currently if the exchange rate for an epoch is not found, we would assign it the default exchange rate while we should've used the exchange rate from the previous existing epoch instead. This PR fixes that.
Test plan
Added some unit tests.
Release notes
Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required.
For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates.
getStakes
API so that we don't overestimate stake rewards of stakes activated during safe mode epochs.